package com.woorigil.android.koreaflower.domain.product;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.woorigil.android.koreaflower.ApiUrl;
import com.woorigil.android.koreaflower.AppContext;
import com.woorigil.android.koreaflower.domain.BaseDao;
import com.woorigil.android.koreaflower.domain.DataContext;
import com.woorigil.android.koreaflower.domain.ProviderCode;
import com.woorigil.android.koreaflower.domain.ProviderUtils;
import com.woorigil.android.koreaflower.support.HttpUtils;
import com.woorigil.android.koreaflower.support.StreamUtils;
import com.woorigil.android.koreaflower.support.StringUtils;

public class DealDao extends BaseDao {

	public DealListResult selectAllDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String url = ApiUrl.allDealListUrl + queryMaker(sid, mainCategoryId, subCategoryId, offset);
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + url;
			
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
				writeDataToFileCache(cacheKey, data);
			}
			
			JSONArray categoryDealsJson = new JSONObject(data).getJSONArray("categoryDeals");
			JSONArray newDealsJson = new JSONObject(data).getJSONArray("newDeals");
			JSONArray freeDealsJson = new JSONObject(data).getJSONArray("freeDeals");
			
			List<Product> categoryDeals = makeDealList(sid, categoryDealsJson);
			List<Product> newDeals = makeDealList(sid, newDealsJson);
			List<Product> freeDeals = makeDealList(sid, freeDealsJson);
			
			DataContext.lastCategoryDealSize = categoryDeals.size();
			DataContext.lastNewDealSize = newDeals.size();
			DataContext.lastFreeDealSize = freeDeals.size();
			
			return new DealListResult(categoryDeals, newDeals, freeDeals);
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	private String readDataFromFileCache(String cacheKey) throws FileNotFoundException, IOException {
		File cacheData = getFileCache().getFile(cacheKey);

		if (cacheData.exists()) {
			return StreamUtils.streamToString(new FileInputStream(cacheData), "UTF-8");
		} else {
			getFileCache().clear();
		}
		return null;
	}
	
	private void writeDataToFileCache(String cacheKey, String data) throws FileNotFoundException, IOException {
		File cacheData = getFileCache().getFile(cacheKey);
		BufferedWriter out = new BufferedWriter(new FileWriter(cacheData));
		out.write(data, 0, data.length());
		out.close();
	}
	
	public List<Product> selectCategoryDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String queryParams = queryMaker(sid, mainCategoryId, subCategoryId, offset);
			String url = ApiUrl.categoryDealListUrl + queryParams;
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + ApiUrl.allDealListUrl + queryParams;
			
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
			}

			JSONArray categoryDealsJson = new JSONObject(data).getJSONArray("categoryDeals");
			List<Product> categoryDeals = makeDealList(sid, categoryDealsJson);
			DataContext.lastCategoryDealSize = categoryDeals.size();
			return categoryDeals;
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	public List<Product> selectNewDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String queryParams = queryMaker(sid, mainCategoryId, subCategoryId, offset);
			String url = ApiUrl.newDealListUrl + queryParams;
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + ApiUrl.allDealListUrl + queryParams;
			
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
			}
			
			JSONArray newDealsJson = new JSONObject(data).getJSONArray("newDeals");
			List<Product> newDeals = makeDealList(sid, newDealsJson);
			DataContext.lastNewDealSize = newDeals.size();
			return newDeals;
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	public List<Product> selectFreeDealList(int mainCategoryId, int subCategoryId, int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String queryParams = queryMaker(sid, mainCategoryId, subCategoryId, offset);
			String url = ApiUrl.freeDealListUrl + queryParams;
			String cacheKey = AppContext.getLastUpdatedTime(getApplicationContext()) + "-" + ApiUrl.allDealListUrl + queryParams;
			
			String data = readDataFromFileCache(cacheKey);
			if (StringUtils.isEmpty(data)) {
				data = HttpUtils.execute(url);
			}
			
			JSONArray freeDealsJson = new JSONObject(data).getJSONArray("freeDeals");
			List<Product> freeDeals = makeDealList(sid, freeDealsJson);
			DataContext.lastFreeDealSize = freeDeals.size();
			return freeDeals;
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}
	
	private String queryMaker(String sid, int mainCategoryId, int subCategoryId, int offset) {
		StringBuffer queryParams = new StringBuffer();
		queryParams.append("?sid=" + sid);
		queryParams.append("&offset=" + offset);
		queryParams.append("&query=");
		queryParams.append("&mainCategoryId=" + mainCategoryId);
		queryParams.append("&subCategoryId=" + subCategoryId);
		return queryParams.toString();
	}	
	
	
	public DealList selectRecentViewDeals(int offset) {
		try {
			String sid = AppContext.getSid(getApplicationContext());
			String url = ApiUrl.recentViewDealListUrl + "?sid=" + sid + "&offset=" + offset;
			String data = HttpUtils.execute(url);
			
			JSONArray jsonArray = new JSONObject(data).getJSONArray("recentViewDeals");
			List<Product> deals = makeDealList(sid, jsonArray);
			return new DealList(deals.size(), deals);
		} catch (Exception e) {
			throw new IllegalStateException(e.getMessage(), e);
		}
	}

	private List<Product> makeDealList(String sid, JSONArray jsonArray) throws JSONException {
		List<Product> deals = new ArrayList<Product>();
		for (int i = 0; i < jsonArray.length(); i++) {
			JSONObject object = jsonArray.getJSONObject(i);
			Product deal = new Product();
			deal.setId(object.getInt("id"));
			deal.setCategoryId(object.getInt("categoryId"));
			deal.setTitle(object.getString("title"));
			deal.setMetaId(object.getString("metaId"));
			deal.setDiscountRate(object.getInt("discountRate"));
			deal.setNowCount(object.getInt("nowCount"));
			deal.setProviderCode(ProviderCode.valueOf(object.getString("providerCode")));
			deal.setOriginalPrice(object.getInt("originalPrice"));
			deal.setSalesPrice(object.getInt("salesPrice"));
			deal.setFromDate(object.getString("saleStartAt"));
			deal.setToDate(object.getString("saleEndAt"));
			deal.setThumbnailImageUrl1(object.getString("imageUrl"));
			deal.setImageUrl1(object.getString("imageUrl1"));
			deal.setDetailViewUrl(ProviderUtils.landingPage(sid, deal.getId(), deal.getProviderCode(), deal.getMetaId()));
			deal.setViewDate(object.getString("viewDate"));
			deals.add(deal);
		}
		
		return deals;
	}
}
